package com.norman.sorry.core.cards;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

import com.norman.sorry.core.moves.IMove;
import com.norman.sorry.core.moves.MoveFactory;
import com.norman.sorry.core.pieces.IPiece;
import com.norman.sorry.core.players.IPlayer;
import com.norman.sorry.core.tiles.ILinkedTile;
import com.norman.sorry.core.tiles.TileUtils;

/**
 * A helper class for creating a concrete version of a card.
 * 
 * @author Brian Norman
 * @version 0.0.1 beta
 * @since 0.0.1 beta
 */
public abstract class AbstractCard implements ICard {

   /**
    * Returns the possible moves for each game piece a player controls if that
    * game piece goes forward or backwards <code>tiles</code> amount. For a game
    * piece to move forward, <code>tiles</code> must be greater than 0.
    * Likewise, if <code>tiles</code> is less than 0, the game pieces will move
    * backwards <code>tiles</code> amount. A game piece will not move if it is
    * in start, in home, or there are not enough tiles in the path it must
    * follow.
    * 
    * @param player
    *           the player that controls the game pieces that can move.
    * @param pieces
    *           the map of what tile each game piece is at.
    * @param tiles
    *           the number of tiles the game pieces can move.
    * @return the possible moves for each game piece a player controls.
    * 
    * @see com.norman.sorry.core.tiles.TileUtils#get(ILinkedTile,
    *      java.awt.Color, int)
    */
   public Collection<IMove> getMoves(IPlayer player, Map<IPiece, ILinkedTile> pieces, int tiles) {
      Collection<IMove> moves = new LinkedList<IMove>();

      for (IPiece p : player.getPieces()) {
         ILinkedTile tile = pieces.get(p);
         if (tile == null || tile.isHome() || tile.isStart()) {
            continue;
         }
         tile = TileUtils.get(tile, p.getColor(), tiles);
         IMove m = MoveFactory.createSingleMove(p, tile);

         if (m != null) {
            moves.add(m);
         }
      }

      return moves;
   }
}
